﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using UberChess.MinMaxAlgorithm;

namespace UberChess.Searching
{
    public delegate void ThreadFinished(object sender, EventArgs e);

    public class Worker : IDisposable
    {
        public event ThreadFinished Finished;
        public int SearchLevel;
        private List<State> _result;
        private Side _playerSide;
        private State _currentState;
        private int _wantedSearchLevel;
        private int _currentSearchLevel;
        private Thread _workerThread;

        private DateTime starttime;
        
        public Worker(Side playerSide, State currentState, int searchLevel)
        {
            _currentSearchLevel = 1;
            _playerSide = playerSide;
            _currentState = currentState;
            _wantedSearchLevel = searchLevel;
            _result = new List<State>();
        }

        public void Start()
        {
            if (_currentSearchLevel <= _wantedSearchLevel)
            {
                _workerThread = new Thread(ThreadProcedure);
                _workerThread.Start();
                while (!_workerThread.IsAlive) ;
            }
        }

        public void ThreadProcedure()
        {
            starttime = DateTime.Now;
            var minMax = new MinMax((State)Copier.Copy(_currentState), _currentSearchLevel, MinMaxType.Minimizer, _playerSide);
            
            Console.WriteLine("Starting search at level: " + _currentSearchLevel);
            var result = minMax.NextMove();

            if(result.Move.isCaptureMove)
                _result.Add(((State)Copier.Copy(_currentState)).CapturePiece(result.Move, ExchangeType.Queen));
            else
            {
                _result.Add(((State)Copier.Copy(_currentState)).MovePiece(result.Move, ExchangeType.Queen));
            }

            Console.WriteLine("Finished in " + (DateTime.Now-starttime));
            _currentSearchLevel++;
            if (Finished != null)
                Finished(this, EventArgs.Empty);
        }

        public State GetResult()
        {
            return _result.Last();
        }

        public void Dispose()
        {
            if (_workerThread != null)
                _workerThread.Abort();
        }
    }

}
